using FireStarterModeller.BO;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using NUnit.Framework;

namespace FireStarterModeller.Test.UI.Relationships
{
    [TestFixture]
    public class TestDMRelationshipSelectorControl
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            UITestUtils.SetupFixture();
        }


        [SetUp]
        public virtual void SetupTest()
        {
            UITestUtils.SetupTest();
        }

        [Test]
        public void Test_ConstructObject_WithControlFactoryNull_ShouldRaiseError()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                new DMRelationshipSelectorControl(null);
                Assert.Fail("expected ArgumentNullException");
            }
                //---------------Test Result -----------------------
            catch (HabaneroArgumentException ex)
            {
                StringAssert.Contains("The argument 'controlFactory' is not valid", ex.Message);
                StringAssert.Contains
                    ("Cannot create an 'DMRelationshipSelectorControl' if the control factory is null", ex.Message);
            }
        }

        //[Ignore("Changing how this works")] 
        [Test]
        public void Test_Construction()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            //---------------Test Result -----------------------
            Assert.AreEqual(1, control.Controls.Count);
            Assert.IsInstanceOf(typeof (IGridControl), control.Controls[0]);
            IGridControl gridControl = (IGridControl) control.Controls[0];
            IButtonGroupControl buttonsControl = gridControl.Buttons;
            Assert.IsTrue(buttonsControl.Visible);
            Assert.IsFalse(gridControl.FilterControl.Visible, "The filter control should not be visible");
            Assert.IsNull(buttonsControl["New"]);
//            Assert.IsNull(buttonsControl["Cancel"]);
            Assert.IsNotNull(buttonsControl["Save"]);
            Assert.IsFalse(buttonsControl["Save"].Visible);
            Assert.IsNull(buttonsControl["Remove"]);
        }

        [Test]
        public void Test_SetSolution_ShouldSetUpComboBoxWithItems()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            DMSolution dmSolution = dmClass.Assembly.Solution;
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmSolution.AllClasses.Count);
            //---------------Execute Test ----------------------
            control.Solution = dmSolution;
            //---------------Test Result -----------------------
            AssertColumnComboBoxItems(1, control, "ReverseRelationship.ClassID");
        }
        [Test]
        public void Test_SetSolution_WithTwoClasses_ShouldSetUpComboBoxWithItems()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            DMSolution dmSolution = dmClass.Assembly.Solution;
            dmSolution.DefaultAssembly.Classes.CreateBusinessObject();
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, dmSolution.AllClasses.Count);
            //---------------Execute Test ----------------------
            control.Solution = dmSolution;
            //---------------Test Result -----------------------
            AssertColumnComboBoxItems(2, control, "ReverseRelationship.ClassID");
        }

        [Test]
        public void Test_WhenAddNewClass_ShouldBeAddedToRelatedClassColumnLookupItems()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            DMSolution dmSolution = dmClass.Assembly.Solution;
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            control.Solution = dmSolution;
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmSolution.AllClasses.Count);
            AssertColumnComboBoxItems(1, control, "ReverseRelationship.ClassID");
            //---------------Execute Test ----------------------
            dmSolution.DefaultAssembly.Classes.CreateBusinessObject();

            //---------------Test Result -----------------------
            //----This works visually but does not work in tests-----------
//            Assert.AreEqual(2, dmSolution.AllClasses.Count);
//            AssertColumnComboBoxItems(2, control, "RelatedClassID");
        }

        private static void AssertColumnComboBoxItems(int expectedItemCount, DMRelationshipSelectorControl actualControl, string columnName)
        {
            Assert.IsTrue(actualControl.GridControl.Grid.Columns.Contains(columnName));
            IDataGridViewColumn column = actualControl.GridControl.Grid.Columns[columnName];
            Assert.IsInstanceOf(typeof(IDataGridViewComboBoxColumn), column);
            IDataGridViewComboBoxColumn comboBoxColumn = (IDataGridViewComboBoxColumn)column;
            Assert.IsNotNull(comboBoxColumn.DataSource);
            Assert.AreEqual(expectedItemCount, comboBoxColumn.Items.Count, "Count of the items in the combo box column was expected to be " + expectedItemCount);
        }

        [Test]
        public void Test_SetDMClass_SetsUpRelationshipsCollectionInGrid()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            dmClass.OwnerRelationships.CreateBusinessObject();
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            //---------------Assert Precondition----------------
            Assert.GreaterOrEqual(dmClass.OwnerRelationships.Count, 1, "There should be one or more relationship");
            //---------------Execute Test ----------------------
            control.Class = dmClass;
            //---------------Test Result -----------------------
            Assert.AreSame(dmClass, control.Class);
            Assert.AreSame(dmClass, control.BusinessObject);
            Assert.AreEqual(dmClass.OwnerRelationships.Count, control.BusinessObjectCollection.Count);
        }

        [Test]
        public void Test_SetBusinesssObject_SetUpRelationshipsCollectionInGrid()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            control.BusinessObject = dmClass;
            //---------------Test Result -----------------------
            Assert.AreSame(dmClass, control.Class);
            Assert.AreEqual(dmClass.Properties.Count, control.BusinessObjectCollection.Count);
        }

        [Test]
        public void TestSetDMClass_Null_ClearsCollectionAndSelectedRelationship()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            control.Class = dmClass;
            //---------------Assert Precondition----------------
            Assert.AreSame(dmClass, control.Class);
            Assert.AreEqual(dmClass.Properties.Count, control.BusinessObjectCollection.Count);
            //---------------Execute Test ----------------------
            control.BusinessObject = null;
            //---------------Test Result -----------------------
            Assert.IsNull(control.Class);
            Assert.IsNull(control.BusinessObject);
            Assert.IsNull(control.SelectedBusinessObject);
            Assert.IsNull(control.BusinessObjectCollection);
        }


        [Test]
        public void TestSetBusinessObject()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            DMRelationship dmRelationship = dmClass.OwnerRelationships.CreateBusinessObject();
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            control.Class = dmClass;
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmClass.OwnerRelationships.Count);
            Assert.AreEqual(1, control.BusinessObjectCollection.Count);
            //---------------Execute Test ----------------------
            control.SelectedBusinessObject = dmRelationship;
            //---------------Test Result -----------------------
            Assert.AreSame(dmRelationship, control.SelectedBusinessObject);
            Assert.AreSame(control.SelectedBusinessObject, control.GridControl.SelectedBusinessObject);
        }

        [Test]
        public void Test_BusinessObjectSelectedEvent()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsShared.CreateUnsavedValidDMClass();
            dmClass.OwnerRelationships.CreateBusinessObject();
            DMRelationship dmRelationship2 = dmClass.OwnerRelationships.CreateBusinessObject();
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            bool fired = false;
            IBusinessObject selectedBO = null;
            control.BusinessObject = dmClass;
            control.BusinessObjectSelected += (sender, e) =>
            {
                fired = true;
                selectedBO = e.BusinessObject;
            };
            
            //---------------Assert PreConditions---------------   
            Assert.IsFalse(fired);
            Assert.IsNull(selectedBO);
            Assert.IsNotNull(control.BusinessObject);
            Assert.AreNotSame(dmRelationship2, control.SelectedBusinessObject);
            //---------------Execute Test ----------------------
            control.SelectedBusinessObject = dmRelationship2;
            //---------------Test Result -----------------------
            Assert.IsTrue(fired);
            Assert.AreSame(selectedBO, control.SelectedBusinessObject);
            Assert.AreSame(selectedBO, dmRelationship2);
        }

       /* [Test]
        public void Test_CheckUserConfirmsDeletionDelegate_WhenRelationshipNull_ShouldReturnTrue()
        {
            //---------------Set up test pack-------------------
            DMRelationshipSelectorControl control = new DMRelationshipSelectorControl(new ControlFactoryWin());
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            bool checkUser = control.CheckUserConfirmsDeletionDelegate();
            //---------------Test Result -----------------------
            Assert.IsTrue(checkUser);
        }*/

//        //ToDetermine whether we will have a new button or not.
////        [Ignore("Changing how this works")] 
////        [Test]
////        public void TestNewButtonClickedCreatesBO_ExistingCollection()
////        {
////            //---------------Set up test pack-------------------
////            DMClass dmClass = TestUtilsShared.CreateSavedDMClass();
////            TestUtilsShared.CreateSavedDMRelationship(dmClass);
////            DMRelationshipSelectorControl classSelectorControl =
////                new DMRelationshipSelectorControl(new ControlFactoryWin());
////            IGridControl gridControl = classSelectorControl.GridControl;
////            classSelectorControl.Class = dmClass;
////            //  ---------------Assert Precondition----------------
////            Assert.AreEqual(1, gridControl.Grid.Rows.Count);
////            BusinessObjectCollection<DMRelationship> classes = dmClass.Properties;
////            Assert.AreEqual(1, classes.Count);
////            //  ---------------Execute Test ----------------------
////            gridControl.Buttons["New"].PerformClick();
////            // ---------------Test Result -----------------------
////            Assert.AreEqual(2, gridControl.Grid.Rows.Count);
////            Assert.AreEqual(2, classes.Count);
////            Assert.AreSame(classes[1], gridControl.SelectedBusinessObject);
////        }
////        [Ignore("Changing how this works")] 
////        [Test]
////        public void TestDeleteButtonDeletesCurrentBO()
////        {
////            // ---------------Set up test pack-------------------
////            //---------------Set up test pack-------------------
////            DMClass dmClass = TestUtilsShared.CreateSavedDMClass();
////            TestUtilsShared.CreateSavedDMRelationship(dmClass);
////            BusinessObjectCollection<DMRelationship> classes = dmClass.Properties;
////            DMRelationshipSelectorControl classSelectorControl = new DMRelationshipSelectorControl(new ControlFactoryWin());
////            IGridControl gridControl = classSelectorControl.GridControl;
////            classSelectorControl.Class = dmClass;
////            IBusinessObject currentBO = gridControl.SelectedBusinessObject;
////            //  ---------------Assert Precondition----------------
////            Assert.AreEqual(2, gridControl.Grid.Rows.Count);
////            Assert.AreEqual(1, classes.Count);
////            //  ---------------Execute Test ----------------------
////            gridControl.Buttons["Remove"].PerformClick();
////            // ---------------Test Result -----------------------
////            Assert.IsTrue(currentBO.Status.IsDeleted);
////            Assert.IsFalse(currentBO.Status.IsDirty);
////            Assert.AreEqual(0, gridControl.Grid.Rows.Count);
////            Assert.AreEqual(0, classes.Count);
////        }
//
////        [Ignore("Changing how this works")] 
////        [Test]
////        public void TestDeleteButton_NoCurrentBO()
////        {
////            //---------------Set up test pack-------------------
////            DMClass dmClass = TestUtilsShared.CreateSavedDMClass();
////            BusinessObjectCollection<DMRelationship> classes = dmClass.Properties;
////            DMRelationshipSelectorControl classSelectorControl = new DMRelationshipSelectorControl(new ControlFactoryWin());
////            IGridControl gridControl = classSelectorControl.GridControl;
////            classSelectorControl.Class = dmClass;
////            IBusinessObject currentBO = gridControl.SelectedBusinessObject;
////            //  ---------------Assert Precondition----------------
////            Assert.AreEqual(0, gridControl.Grid.Rows.Count);
////            Assert.AreEqual(0, classes.Count);
////            Assert.IsNull(currentBO);
////            //  ---------------Execute Test ----------------------
////            gridControl.Buttons["Remove"].PerformClick();
////            // ---------------Test Result -----------------------
////            Assert.AreEqual(0, gridControl.Grid.Rows.Count);
////            Assert.AreEqual(0, classes.Count);
////        }

//        [Test]
//        public void TestCancelButton_ClickRestoresSavedObject()
//        {
//            //---------------Set up test pack-------------------
//            DMClass dmClass = TestUtilsShared.CreateSavedDMClass();
//            dmClass.OwnerRelationships.CreateBusinessObject();
//            BusinessObjectCollection<DMRelationship> relationships = dmClass.OwnerRelationships;
//            DMRelationshipSelectorControl relationshipSelectorControl = new DMRelationshipSelectorControl(new ControlFactoryWin());
//            IGridControl gridControl = relationshipSelectorControl.GridControl;
//            relationshipSelectorControl.BusinessObject = dmClass;
//            DMRelationship currentBO = (DMRelationship) gridControl.SelectedBusinessObject;
//            currentBO.RelationshipName = TestUtilsShared.GetRandomString();
//            //  ---------------Assert Precondition----------------
//            Assert.AreEqual(1, gridControl.Grid.Rows.Count);
//            Assert.AreEqual(1, relationships.Count);
//            Assert.IsTrue(currentBO.Status.IsDirty);
//            //  ---------------Execute Test ----------------------
//            gridControl.Buttons["Cancel"].PerformClick();
//            // ---------------Test Result -----------------------
//            Assert.IsFalse(currentBO.Status.IsDirty);
//        }
//
//        [Test]
//        public void TestCancelButton_Click_NoObjecctSelected()
//        {
//            //---------------Set up test pack-------------------
//            DMClass dmClass = TestUtilsShared.CreateSavedDMClass();
//            BusinessObjectCollection<DMRelationship> relationships = dmClass.OwnerRelationships;
//            DMRelationshipSelectorControl propertySelectorControl = new DMRelationshipSelectorControl(new ControlFactoryWin());
//            IGridControl gridControl = propertySelectorControl.GridControl;
//            propertySelectorControl.Class = dmClass;
//            DMRelationship currentBO = (DMRelationship) gridControl.SelectedBusinessObject;
//            //  ---------------Assert Precondition----------------
//            Assert.AreEqual(0, gridControl.Grid.Rows.Count);
//            Assert.AreEqual(0, relationships.Count);
//            Assert.IsNull(currentBO);
//            //  ---------------Execute Test ----------------------
//            gridControl.Buttons["Cancel"].PerformClick();
//            // ---------------Test Result -----------------------
//            Assert.AreEqual(1, gridControl.Grid.Rows.Count);
//            Assert.AreEqual(0, relationships.Count);
//        }
    }
}